﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.MesMsgQueues;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.TibcoMessage;
using HamcoWcs.Service.Common;
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

namespace HamcoWcs.Service.Mes.Parsers
{
    /// <summary>
    /// 目的地变更,只有目的地为清洗机，且未到达二楼提升机口CV的场景可以修改目的地
    /// </summary>
    public class MesMsgParser_ChangePalletDestinationRequest : MesMsgParserBase
    {

        public override void HandleEvent(MesMsgQueue message)
        {
            string xml = message.Content;
            var jobMessage = XmlHelper.Deserialize<ChangePalletDestinationMessage>(xml);

            try
            {
                jobMessage.SetReplyName();

                var oldLoc = jobMessage.Body.OldDestinationMachineName;
                var newLoc = jobMessage.Body.NewDestinationMachineName;

                if (string.IsNullOrEmpty(oldLoc))
                    throw new MESJobException(34, "Empty DestinationMachineName");
                if (string.IsNullOrEmpty(newLoc))
                    throw new MESJobException(34, "Empty DestinationMachineName");

                if (!PPKMACHINENAMES.Contains(oldLoc)
                 || !PPKMACHINENAMES.Contains(newLoc))
                    throw new MESJobException(35, "Illegal destination machine");

                if (oldLoc == newLoc)
                    throw new MESJobException(36, "Same destination machine");

                var mainTask = _wcsDbContext.MainTasks
                                            .Where(x => x.TaskId == jobMessage.Body.TransportJobName)
                                            .Include(x => x.SubTasks)
                                            .FirstOrDefault()
                    ?? throw new MESJobException(39, "Not find corresponding move task"); ;

                switch (Enum.Parse<EnumMainTaskStatus>(mainTask.TaskStatus))
                {
                    case EnumMainTaskStatus.NewTask:
                    case EnumMainTaskStatus.Ready:
                    case EnumMainTaskStatus.OnProgress:
                        //mainTask.OldDesMachine = mainTask.DesMachine;
                        mainTask.OldDesPosition = mainTask.DesPosition;
                        mainTask.OldDesType = mainTask.DesType;
                        mainTask.OldDesZone = mainTask.DesZone;

                        mainTask.DesMachine = newLoc;
                        mainTask.DesPosition = jobMessage.Body.NewDestinationPositionName;
                        mainTask.DesType = jobMessage.Body.NewDestinationPositionType;
                        mainTask.DesZone = jobMessage.Body.NewDestinationZoneName;

                        // todo 修改MainTaskType
                        if (mainTask.TaskStatus == EnumMainTaskStatus.NewTask.ToString()
                         || mainTask.TaskStatus == EnumMainTaskStatus.Ready.ToString())
                        {
                            mainTask.SubTasks.Clear();
                            mainTask.TaskStatus = EnumMainTaskStatus.NewTask.ToString();
                        }
                        else
                        {
                            if (mainTask.TotalSubTaskNum - mainTask.ActiveSubTaskId >= 2)
                            {
                                var stask = mainTask.SubTasks.FirstOrDefault(x => x.ToLoc == oldLoc)
                                    ?? throw new MESJobException(38, $"Not found the subTask that destination machine is '{oldLoc}'");

                                stask.ToLoc = newLoc;
                            }
                            else
                            {
                                throw new MESJobException(37, "Moving started, unable to modify destination");
                            }
                        }



                        message.Return = XmlHelper.Serialize(jobMessage);
                        message.Status = (int)EnumMesMsgStatus.WcsExcuted;

                        _logger.AddWcsRunLog(mainTask.UnitId, $"MES变更目的地{oldLoc}->{newLoc}，TaskId:{mainTask.TaskId}");
                        break;
                    case EnumMainTaskStatus.Finished:
                    case EnumMainTaskStatus.Error:
                    case EnumMainTaskStatus.Delete:
                    case EnumMainTaskStatus.Cancel:
                    default:
                        throw new MESJobException(40, $"Change pallet destination refuse:the task has '{mainTask.TaskStatus}'");
                }

                _wcsDbContext.SaveChanges();
            }
            catch (MESJobException ex)
            {
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                var r = XmlHelper.Serialize(jobMessage);
                r = XmlHelper.SetNGReturn(r, ex.ErrorCode.ToString(), ex.Message);
                message.Return = r;
            }
            catch (Exception ex)
            {
                message.Status = (int)EnumMesMsgStatus.WcsExcuted;
                AddSystemErrorLog(xml, ex);
            }
        }


        public MesMsgParser_ChangePalletDestinationRequest(ILoggerService loggerService, WcsDbContext wcsDbContext, IMapper mapper)
            : base(loggerService, wcsDbContext, mapper)
        {
        }

        public override string EventName => "ChangePalletDestinationRequest";

        private static List<string> PPKMACHINENAMES = new List<string>()
        {
            "CJMCV100",
            "CJMCV200",
            "CJMCV800",
            "CJMCV900",
            "CJMCVA00",
        };

    }
}
